use chrono::{DateTime, Duration, Utc};
use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};

#[derive(Debug, Default, Serialize, Deserialize)]
pub struct Claims {
    // 这里的数据会经过Base64编码, 所以不要存放隐私数据
    username: String,
    id: u32,
    // 此令牌的过期时间
    exp: usize,
}

fn main() {
    // 设置过期时间
    let exp: DateTime<Utc> = Utc::now() + Duration::minutes(1);

    let my_claims = Claims {
        // 往令牌里放一些无关紧要的数据, 比如用户名"法外狂徒张三", 用户id
        username: "法外狂徒张三".to_string(),
        id: 1,
        // 将过期时间转化成时间戳
        exp: exp.timestamp() as usize,
    };

    // 用来加密数据的密钥
    let key = String::from("secret");

    // 进行加密, 默认是HSA256算法
    let token = encode(
        &Header::default(),
        &my_claims,
        &EncodingKey::from_secret(key.as_bytes()),
    )
    .unwrap();

    println!("加密字符串如下:\n{:?}\n", token);

    // 用密钥解密数据
    let token = decode::<Claims>(
        &token,
        &DecodingKey::from_secret("secret".as_ref()),
        &Validation::default(),
    )
    .unwrap();

    println!("解密格式如下:\n{:#?}", token.claims)
}
